# -*- coding: utf-8 -*-
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
# (see spyder/__init__.py for details)

"""
Variable Explorer Plugin.
"""

# Third-party imports
from spyder_kernels.utils.iofuncs import iofunctions

# Local imports
from spyder.api.plugins import Plugins, SpyderDockablePlugin
from spyder.api.plugin_registration.decorators import (
    on_plugin_available, on_plugin_teardown)
from spyder.api.shellconnect.mixins import ShellConnectPluginMixin
from spyder.api.translations import _
from spyder.plugins.variableexplorer.confpage import (
    VariableExplorerConfigPage)
from spyder.plugins.variableexplorer.widgets.main_widget import (
    VariableExplorerWidget)


class VariableExplorer(SpyderDockablePlugin, ShellConnectPluginMixin):
    """
    Variable explorer plugin.
    """
    NAME = 'variable_explorer'
    REQUIRES = [Plugins.IPythonConsole, Plugins.Preferences]
    OPTIONAL = [Plugins.Plots]
    TABIFY = None
    WIDGET_CLASS = VariableExplorerWidget
    CONF_SECTION = NAME
    CONF_FILE = False
    CONF_WIDGET_CLASS = VariableExplorerConfigPage
    DISABLE_ACTIONS_WHEN_HIDDEN = False

    # Open binary data files in this plugin
    FILE_EXTENSIONS = [
        ext for ext in iofunctions.load_funcs
        if ext not in ['.csv', '.txt', '.json']
    ]

    # ---- SpyderDockablePlugin API
    # ------------------------------------------------------------------------
    @staticmethod
    def get_name():
        return _('Variable explorer')

    @staticmethod
    def get_description():
        return _("Explore, edit, save and load the lists, arrays, dataframes "
                 "and other global variables generated by running your code.")

    @classmethod
    def get_icon(cls):
        return cls.create_icon('variable_explorer')

    def on_initialize(self):
        widget = self.get_widget()
        widget.sig_open_preferences_requested.connect(self._open_preferences)
        widget.sig_show_figure_requested.connect(self._show_figure)

    @on_plugin_available(plugin=Plugins.Plots)
    def on_plots_available(self):
        self.get_widget().set_plots_plugin_enabled(True)

    @on_plugin_teardown(plugin=Plugins.Plots)
    def on_plots_teardown(self):
        self.get_widget().set_plots_plugin_enabled(False)

    @on_plugin_available(plugin=Plugins.Preferences)
    def on_preferences_available(self):
        preferences = self.get_plugin(Plugins.Preferences)
        preferences.register_plugin_preferences(self)

    @on_plugin_teardown(plugin=Plugins.Preferences)
    def on_preferences_teardown(self):
        preferences = self.get_plugin(Plugins.Preferences)
        preferences.deregister_plugin_preferences(self)

    def open_file(self, filename: str):
        """
        Load data file in variable explorer.
        """
        self.get_widget().import_data([filename])

    # ---- Private API
    # -------------------------------------------------------------------------
    def _open_preferences(self):
        """Open the Preferences dialog in the Variable Explorer section."""
        self._main.show_preferences()
        preferences = self.get_plugin(Plugins.Preferences)
        if preferences:
            container = preferences.get_container()
            dlg = container.dialog
            index = dlg.get_index_by_name(self.NAME)
            dlg.set_current_index(index)

    def _show_figure(self, image, mime_type, shellwidget):
        """
        Show figure in Plots plugin.

        This shows the figure in the figure browser associated with the given
        shellwidget. The shellwidget is activated and the Plots plugin and the
        window containing the Plots plugin are both raised so that the user
        will see the figure.

        Parameters
        ----------
        image: bytes
            The image to show. SVG images should be encoded so that the type
            of this parameter is `bytes`, not `str`.
        mime_type: str
            The image's mime type.
        shellwidget: ShellWidget
            The shellwidget associated with the figure.
        """
        ipython_console = self.get_plugin(Plugins.IPythonConsole)
        if ipython_console:
            ipython_console.set_current_shellwidget(shellwidget)

        plots = self.get_plugin(Plugins.Plots)
        if plots:
            if mime_type == 'image/svg+xml':
                image = image.decode()
            plots.add_plot(image, mime_type, shellwidget)
